package com.sltx.util;

import com.google.gson.Gson;
import com.quantum.dubbo.core.utils.AuthUtils;
import com.sltx.util.http.ConfigUtils;
import com.sltx.util.http.HttpRequest;
import com.sltx.vo.PostJsonParam;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: liuying
 * Date: 16-6-30
 * Time: 上午9:38
 * To change this template use File | Settings | File Templates.
 */
public class HttpUtils {
    private CloseableHttpClient httpClient;
    private HttpContext context;
    //public static String CONIG_FILE_NAME = "thea-key.properties";
    private final Key key;
    private static final Logger log = LoggerFactory
            .getLogger(HttpUtils.class);

    public HttpUtils(Key key) {
        this.key = key;
        this.context = HttpClientContext.create();
        this.httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setMaxConnTotal(200).
                setMaxConnPerRoute(400).setRetryHandler(retryHandler).build();
    }

    // ----------------------------------------------------------------重试策略
    HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {

        @Override
        public boolean retryRequest(IOException exception, int executionCount,
                                    HttpContext context) {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//
//            }
            System.out.println("Exception:" + exception.getMessage() + "重试 第"
                    + executionCount + "次");

            if (executionCount >= 2) {
                return false;
            }
            return true;
            // if (exception instanceof NoHttpResponseException) {
            // return true;
            // }
            // if (exception instanceof SocketException) {
            // return true;
            // }
            // if (exception instanceof ConnectionPoolTimeoutException) {
            // return true;
            // }
            //
            // return true;

        }
    };
    // ------------------------------------------------------------------创建连接池

    ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

        public String handleResponse(final HttpResponse response)
                throws ClientProtocolException, IOException {

            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 && status < 300) {
                HttpEntity entity = response.getEntity();

                return entity != null ? EntityUtils.toString(entity) : null;
            } else {
                throw new ClientProtocolException(
                        "Unexpected response status: " + status);
            }

        }

    };

    public void closeClient() {
//
        try {
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
            log.info(e.getMessage());
        }


    }

    // 设置超时时间
    static RequestConfig requestConfig = RequestConfig.custom()
            .setConnectionRequestTimeout(40000).setConnectTimeout(40000)
            .setSocketTimeout(40000).build();

    /*public String sendRequest(PostJsonParam jsonParam) {
        try {
            String url = CommonUtils.getProperty(CONIG_FILE_NAME, "url");
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
//            httpPost.addHeader("Connection","Keep-Alive");
            String uid = jsonParam.getUid();
            String params = JSONEncoder.encode(jsonParam);
//            log.info("=================请求参数===========");
//            log.info(params);
//            log.info("=================================");

            Map<String, Object> map = com.quantum.dubbo.core.utils.AuthUtils.encode(params, key);
            String dataValue = JSONEncoder.encode(map);
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("uid", uid));
            nvps.add(new BasicNameValuePair("data", dataValue));

            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            long startTime = System.currentTimeMillis();
            String result = httpClient.execute(httpPost, responseHandler);
            httpPost.releaseConnection();
            long endTime = System.currentTimeMillis();
            log.info(params + "请求主体加用时：" + (endTime - startTime));
            httpPost.abort();
            //closeClient();

            long startTime1 = System.currentTimeMillis();
            result = URLDecoder.decode(result, "UTF-8");
            Map<String, Object> resultMap = JSONDecoder.decode(result);
            // ----------------解密数据-------------------------------
            String value = com.quantum.dubbo.core.utils.AuthUtils.decode(resultMap, key);
            long endTime1 = System.currentTimeMillis();
            log.info( "请求主体加用时：" + (endTime1 - startTime1));
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            closeClient();
            log.info(e.getMessage());
            return null;
        } finally {
           closeClient();
        }
    }*/
    
    public String sendRequest(PostJsonParam jsonParam) {
    	//AuthUtils au = new AuthUtils();
    	//加密过程
        String uid =  jsonParam.getUid(); //用户id
        String serverName = jsonParam.getService(); //服务方法名称
        Map<String, String> param = jsonParam.getParams();
        String serviceUrl = ConfigUtils.getProperty(Conversion.CONIG_DATACENTER_URL,"");
        String serverParams = getServerJsonStr(uid,serverName,param);
        String postParams = MessageFormat.format("uid={0}&data={1}", uid, getPostJsonStr(serverParams));
    	
	try {
		//获取数据   String postParams = MessageF
        Gson gson = new Gson();
        String result = HttpRequest.sendPost(serviceUrl, postParams);
        result = URLDecoder.decode(result, "UTF-8");
    	//转换数据
        //Map<String, Object> resultMap = JSONDecoder.decode(result);
        Map<String, Object> resultMap = gson.fromJson(result,Map.class);
		// ----------------解密数据-------------------------------
		long startTime1 = System.currentTimeMillis();
		String value = RasAndDesDecode(resultMap);
		long endTime1 = System.currentTimeMillis();
        log.info( "请求主体加用时：" + (endTime1 - startTime1)); 
        //closeClient();
		return value;
    }catch (UnsupportedEncodingException ex) {  
        ex.printStackTrace();
        log.info(ex.getMessage());
        closeClient();
        return "";
    } catch (Exception e) {
    	//TODO 解密出错，说明返回数据未加密
        e.printStackTrace();
        closeClient();
        log.info(e.getMessage());
        return "";
    } finally {
       //closeClient();
    }
    }
    
    /**
     * 解密过程
     *
     * @param data
     * @return
     * @throws Exception
     */
    private String RasAndDesDecode(Map<String, Object> data) throws Exception {
        return AuthUtils.decode(data, key);
    }
    
    /**
     * 服务参数加密
     *
     * @param serverParams
     * @return 返回加密后的密文
     * @throws Exception
     */
    private String getPostJsonStr(String serverParams) {
        Map<String, Object> authParams;
        String  urlEncoder = null;
        Gson gson = new Gson();
		try {
			authParams = AuthUtils.encode(serverParams, key);
			//urlEncoder = URLEncoder.encode(JSONEncoder.encode(authParams), "UTF-8") ;
            urlEncoder = URLEncoder.encode(gson.toJson(authParams), "UTF-8") ;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}catch (Exception e) {
			e.printStackTrace();
		}
        return urlEncoder;
    }
    
    /**
     * 服务参数
     *
     * @param uid        用户Uid
     * @param serverName 服务方法名称
     * @return 服务相关参数的JSON数据
     */
    private String getServerJsonStr(String uid, String serverName,Map<String, String> params) {
        Map<String, Object> conditoinMap = new HashMap<String, Object>();
        conditoinMap.put("uid", uid);
        conditoinMap.put("service", serverName);
        Gson gson = new Gson();

      /*  Map<String, Object> params = new HashMap<String, Object>();
        params.put("keyword", "用友网络");
        params.put("type", "0");*/

        conditoinMap.put("params", params);

        //return JSONEncoder.encode(conditoinMap);

        return gson.toJson(conditoinMap);
    }
}
